<%-- 
    Document   : FlibaEducationView_v0.2
    Created on : 12-12-2011, 16:07:15
    Author     : phil
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head> 
        <script type="text/javascript" src="javaScripts/ThreeScript/Three.js"></script>
        <script type="text/javascript" src="javaScripts/jquery-1.7.js"></script>
        <script type="text/javascript" src="javaScripts/webgl-utils.js"></script>
        <script type="text/javascript">
        var xmlHttp;
            
            function createXmlHttpRequest() {
                if(window.ActiveXObject) {
                    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
                }
                else 
                    if(window.XMLHttpRequest) {
                    xmlHttp=new XMLHttpRequest();
                    }
            }
            
            function startRequest() {
              createXmlHttpRequest();
              xmlHttp.open("GET","http://localhost:8080/FlibaView/ArrayServlet" ,true)
              xmlHttp.onreadystatechange=handleStateChange;
              xmlHttp.send();

            }
            
            function handleStateChange() {
                if(xmlHttp.readyState==4) {
                    if(xmlHttp.status==200) {
                        // Generates a variable called 'array'
                          eval(xmlHttp.responseText);
                          scaleCubes(); 
                          setCubesVisibility()
                    }
                    else {
                       alert("Error loading pagen"+ xmlHttp.status +
                        ":"+xmlHttp.statusText);
                    }
                }
            }
        </script>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
			body {
				background: #000;
				color: #EEE;
				padding: 0;
				margin: 0;
				font-weight: bold;
				overflow: hidden;

				font-family: Monospace;
				font-size: 13px;
				text-align: left;
			}
			#info {
				position: absolute;
				top: 0px;
				width: 100%;
				padding: 5px;
				z-index: 20;
			}
		</style>
        <title>JSP Page</title>
    </head>
    <body onload="startRequest()" oncontextmenu="return false;">

    Document   : FlibaEducationView_v0.2
    Created on : 12-12-2011, 16:07:15
    Author     : phil

        <div id="info">
                        <br/>
                        <p id ="TopText"> Dette er en prototype lavet med webGL, Three.js og AJAX.</p>
            <p id ="InfoText"> Roter kortet: hold space inde + venster musseknap.</p>
            <p id ="InfoText"> Vælg lokation: Klik på kortet med højre musse knap</p>
            <p id ="warning"> nothing</p>
            <p id ="warning2"> nothing</p>
            <p id ="warning3"> nothing</p>
            
            <select id ="radiusInput">
              <option value="5">close</option>
              <option value="10">fair</option>
              <option value="15">far</option>
              <option value="-1">all</option>
            </select>
            <button onclick="startRequest();">
                accept radius
            </button>
        </div>
    </body>
    <script type="text/javascript">
        // set the scene size
        var width = window.innerHeight;
        var height = window.innerWidth;
        var container;
        // dimension for the grid of cubes
        var RES = 50;
        var DIMENSION = RES*RES;
        var CUBE_SIZE = 2;
        
        var selectionRadius = 5;
        
        // basic webGL stiff
        var camera;
        var cameraTargetPosY = -50;
        var cameraLookAtVector = new THREE.Vector3( RES, cameraTargetPosY, RES );
        var renderer;
        var scene;
        var projector;
        var textureImage = THREE.ImageUtils.loadTexture( 'textures/scandinavia0.png');
        var light;
        var group;
        
        // controls
        var currentlyPressedKeys = {};
        var currentlyMousePressedKey ={};
        var currentlyMousePosX;
        var currentlyMousePosY;
        var mouseLeftDown = false;
        var lastMouseX = null;
        var lastMouseY = null;
        var selectionCenter =[RES/2, RES/2];
        var lastVisibleCube = [0];
        
        // array for AJAX info
        var array = new Array();
        var arrayMax = 0;

        function init(){
        
            // create a WebGL renderer, camera
            // and a scene
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera( 20, width / height, 1, 2000 );
            camera.position.y = 400;
            camera.position.x = 4* RES * Math.cos(663/500 );
            camera.position.z = 4* RES * Math.sin(663/500 );
            camera.lookAt( cameraLookAtVector );

            container = document.createElement( 'div' );
            document.body.appendChild( container );
            document.getElementById("warning").innerHTML=width;
            document.getElementById("warning2").innerHTML=height;

            renderer = new THREE.WebGLRenderer({antialias: true, clearAlpha: 1, clearColor: 0x000000});
            renderer.setSize(width, height);
            renderer.sortObjects = false;
            renderer.autoClear = false;

            renderer.shadowMapEnabled = true;
            renderer.shadowMapSoft = true;

            renderer.shadowCameraNear = 3;
            renderer.shadowCameraFar = camera.far;
            renderer.shadowCameraFov = 50;

            renderer.shadowMapBias = 0.0039;
            renderer.shadowMapDarkness = 0.5;
            renderer.shadowMapWidth = 512;
            renderer.shadowMapHeight = 512;

            scene.add( camera ); // add camera to scene

            // attach the render-supplied DOM element
            container.appendChild( renderer.domElement );

            // Cubes
            var geometry;
            group = new THREE.Object3D();

            geometry = new THREE.CubeGeometry( CUBE_SIZE/2, CUBE_SIZE, CUBE_SIZE/2 );
            geometry.applyMatrix( new THREE.Matrix4().setTranslation( 0, CUBE_SIZE / 2, 0 ) );
            material = new THREE.MeshLambertMaterial( { color: 0xd0FFd0 } );

            for ( var i = 0; i < DIMENSION; i ++ ) {
                material = new THREE.MeshLambertMaterial( { color: 0xFF3333 } );
                var cube = new THREE.Mesh( geometry, material );
                cube.position.x = CUBE_SIZE + ( ( i % RES ) * CUBE_SIZE )-1;
                cube.position.z = CUBE_SIZE + ( Math.floor( i / RES ) * CUBE_SIZE )-1;
                cube.scale.y = 1;
                cube.castShadow = true;
              //  cube.receiveShadow = true;
                cube.visible = false;
                group.add( cube );

            }
            scene.add( group ); // add cubes to scene

            //create plane that is a cube
            material = new THREE.MeshLambertMaterial( { map: textureImage } );
            geometry = new THREE.CubeGeometry( RES*CUBE_SIZE, RES*CUBE_SIZE, 1 );
            plane = new THREE.Mesh(geometry, material);
            plane.castShadow = false; //no need to drop shadow
            plane.receiveShadow = true;
            plane.position.x = (RES*CUBE_SIZE)/2;
            plane.position.z = (RES*CUBE_SIZE)/2;
            plane.rotation.x = - 90 * Math.PI / 180;

            scene.add(plane);


            // create light
            scene.add( new THREE.AmbientLight( 0x808080 ) );

            var light = new THREE.SpotLight( 0xffffff, 1.25 );
            light.position.set( - 500, 900, 600 );
            light.target.position.set( CUBE_SIZE, 0, CUBE_SIZE );
            light.castShadow = true;

            scene.add( light );
            
            //interaktivity
            projector = new THREE.Projector();
            
            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            document.addEventListener( 'mouseup', onDocumentMouseUp, false );
            document.addEventListener( 'mousemove', onMouseMove, false );
            window.addEventListener( 'resize', onWindowResize, false );
            document.addEventListener( 'keypress', onKeyPress, false );
            document.addEventListener( 'keyup', onKeyUp, false );

            function onWindowResize( event ) {
                windowResize();
            };
            
            function windowResize(){
                width = window.innerWidth;
                height = window.innerHeight;

                renderer.setSize( width, height );

                camera.aspect = width / height;
                camera.updateProjectionMatrix();
            }
            
            function onKeyPress(event){
                currentlyPressedKeys[event.keyCode] = true;
                if (currentlyPressedKeys[event.keyCode] == 38){ //if keypressed is arrow up
                    
                }
                if (currentlyPressedKeys[event.keyCode] == 40){ //if keypressed is arrow down
                    
                }
            }
            
            function onKeyUp(event) {
                currentlyPressedKeys[event.keyCode] = false;
            }
            
            var positionX = 663;
            var positionY = 400;
            function onMouseMove(event) {
                if (!mouseLeftDown) {
                    return;
                }
                
                if (currentlyPressedKeys[32] == true) {

                    var newX = event.clientX;
                    var newY = event.clientY;
                    
                    if(positionY + ((newY - lastMouseY)/10)>100  ){
                        positionY = positionY + (newY - lastMouseY);
                        cameraTargetPosY = cameraTargetPosY - ((newY - lastMouseY)/7);
                        cameraLookAtVector = new THREE.Vector3( RES, cameraTargetPosY, RES );
                    }
                    positionX = positionX + newX - lastMouseX;
                    
                    
                    camera.position.y = positionY;
                    camera.position.x = (4* RES) * Math.cos( positionX/500 );
                    camera.position.z = (4* RES) * Math.sin( positionX/500 );
                    camera.lookAt( cameraLookAtVector );
                    
                    document.getElementById("warning").innerHTML= newY;
                    document.getElementById("warning2").innerHTML= newX;
                    
                    lastMouseX = newX;
                    lastMouseY = newY;
                }
            }
            function onDocumentMouseUp( event ) {
                mouseLeftDown = false;
            }

            function onDocumentMouseDown( event ) {
                if(event.button == 0){
                    mouseLeftDown = true;
                    lastMouseX = event.clientX;
                    lastMouseY = event.clientY;
                }
                else if(event.button == 2){
                    mouseLeftDown = false;
                    event.preventDefault();

                    var vector = new THREE.Vector3( ( event.clientX / width ) * 2 - 1, - ( event.clientY / height ) * 2 + 1, 1 );
                    projector.unprojectVector( vector, camera );
                    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
                    var intersects = ray.intersectObject(plane);

                    if ( intersects.length > 0 ) {
                        var point = intersects[ 0 ].point;
                        var x = Math.floor( point.x / (CUBE_SIZE) );
                        var y = Math.floor( point.z / (CUBE_SIZE) );
                        selectionCenter[0] = x;
                        selectionCenter[1] = y;
                        
                        scaleCubes();
                        setCubesVisibility();
                    }
                }
            }
            windowResize();
        }
        // function call from button in browser
        function scaleCubes() {
            if (-1 == document.getElementById("radiusInput").value){
                selectionRadius = RES*1.5;
            } else {
                selectionRadius = document.getElementById("radiusInput").value;
            }
            var red = 0xFF0000;
            var green = 0x00FF00;
            var blue = 0x0000FF;
            for(var i=0; i<RES; i++){
                for(var j=0; j<RES; j++){
                    group.children[i*RES+j].scale.y = array[i][j];
                    if(array[i][j] < 3){
                    group.children[i*RES+j].material =(new THREE.MeshLambertMaterial( { color: blue } ));
                    } else if (array[i][j] >3){
                        group.children[i*RES+j].material =(new THREE.MeshLambertMaterial( { color: red } ));
                    } else {
                        group.children[i*RES+j].material =(new THREE.MeshLambertMaterial( { color: green } ));
                    }
                }
            }
        }
        function setCubesVisibility(){
            for(i = 0; i<lastVisibleCube.length ; i++){
                group.children[lastVisibleCube[i]].visible =false;
            }

            lastVisibleCube = [];

            for(i = 0 ; i < selectionRadius*2 ; i++){
                for(j = 0 ; j < selectionRadius*2 ; j++){
                    if (
                        Math.pow(-selectionRadius+i, 2) + Math.pow(-selectionRadius+j,2) < Math.pow(selectionRadius,2) && // use pataroros to determin id cube is inside radius a^2+b^2 =c^2
                        (((selectionCenter[1] +j-selectionRadius)))>=0 && (((selectionCenter[1] +j-selectionRadius)))<RES  && // can't select object outside plane on y- that don't exits'
                        ((i+selectionCenter[0]-selectionRadius))>=0 && (((i+selectionCenter[0]-selectionRadius)<RES &&
                        group.children[((selectionCenter[1] +j-selectionRadius)*RES)+(i+selectionCenter[0]-selectionRadius)].scale.y > 1)))  // can't select object outside plane on x- that don't exits'
                    {
                        lastVisibleCube.push(((selectionCenter[1] +j-selectionRadius)*RES)+(i+selectionCenter[0]-selectionRadius))
                        group.children[((selectionCenter[1] +j-selectionRadius)*RES)+(i+selectionCenter[0]-selectionRadius)].visible = true;
                    }
                }
            }
        }
        
        init();
        animate();

        function animate() {
                requestAnimationFrame( animate );
                render();
        }

        function render() {
            renderer.render( scene, camera );
        }
        
        </script>
</html>
